package com.wty.app.bthcar.bluetooth;

import android.app.Activity;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

import com.wty.app.bthcar.info.DeviceBean;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class BluetoothBLEChatService {
    public static String HEART_RATE_MEASUREMENT = "0000ffe1-0000-1000-8000-00805f9b34fb";
    private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

    boolean connect = false;
    //蓝牙特征值
    private static BluetoothGattCharacteristic target_chara = null;
    /**
     * 广播接收器，负责接收BluetoothLeService类发送的数据
     */
    public final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action))//Gatt连接成功
            {
                if (statusListener!=null){
                    statusListener.onChange(deviceBean.getDeviceName(), true);
                }
                connect = true;
                //更新连接状态
                System.out.println("BroadcastReceiver :" + "device connected");
                Log.e("getCOnnectStatu"," device connected");
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED//Gatt连接失败
                    .equals(action))
            {
                if (statusListener!=null){
                    statusListener.onChange(deviceBean.getDeviceName(), false);
                }
                connect = false;
                //更新连接状态
                System.out.println("BroadcastReceiver :"
                        + "device disconnected");
                Log.e("getCOnnectStatu","device disconnected");
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED//发现GATT服务器
                    .equals(action))
            {
                // Show all the supported services and characteristics on the
                // user interface.
                //获取设备的所有蓝牙服务
                displayGattServices(mBluetoothLeService
                        .getSupportedGattServices());
                System.out.println("BroadcastReceiver :"
                        + "device SERVICES_DISCOVERED");
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action))//有效数据
            {
                //处理发送过来的数据
                try {
                    if (intent.getExtras().getString(
                            BluetoothLeService.EXTRA_DATA)!=null) {
                        displayData(intent.getExtras().getString(
                                BluetoothLeService.EXTRA_DATA), intent);
                        System.out.println("BroadcastReceiver onData:"
                                + intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    };
    private String revStr;

    /**
     * @Title: displayData
     * @Description: TODO(接收到的数据在scrollview上显示)
     * @param @param rev_string(接受的数据)
     * @return void
     * @throws
     */
    private void displayData(String rev_string,Intent intent)
    {
        try {
            byte[] data = intent.getByteArrayExtra("BLE_BYTE_DATA");
            if(data==null)
                System.out.println("data is null!!!!!!");
            rev_string = new String(data, 0, data.length, "GB2312");//GB2312编码

        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        revStr += rev_string;
        //更新UI
        Log.e("getPrintlllls",revStr+"");
        /*runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                rev_tv.setText(revStr);
                rev_sv.scrollTo(0, rev_tv.getMeasuredHeight());
                System.out.println("rev:" + revStr);
            }
        });*/

    }

    private Activity activity;
    private DeviceBean deviceBean;

    private OnStatusListener statusListener;

    public BluetoothBLEChatService(DeviceBean deviceBean, OnStatusListener onStatusListener) {
        this.deviceBean = deviceBean;
        this.statusListener = onStatusListener;
    }

    private ExecutorService executorService = Executors.newFixedThreadPool(4); // 使用单线程线程池

    public void init(Activity activity){
        this.activity= activity;
        activity.registerReceiver(mGattUpdateReceiver,makeGattUpdateIntentFilter());
        Intent gattServiceIntent = new Intent(activity, BluetoothLeService.class);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                activity.bindService(gattServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
            }
        },1000);

    }

    public void sendMsg(String cmd){
        /*if (executorService ==null){
            executorService =Executors.newFixedThreadPool(4); // 使用单线程线程池
        }

        executorService.submit(new sendDataThread());*/
        Log.e("getPrintLoagThre",cmd);
        new sendDataThread(cmd);
    }

    public class sendDataThread implements Runnable{

        private String msg="";
        public sendDataThread(String cmd) {
            super();
            new Thread(this).start();
            this.msg = cmd;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            byte[] buff =null;
            try {
                buff =msg.toString().getBytes("GB2312");
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            int[] sendDatalens = dataSeparate(buff.length);
            Log.d("AppRunArrayLenght","buff.length:"+buff.length);
            int length = 0;
            for(int i=0;i<sendDatalens[0];i++)
            {
                byte[] dataFor20 = new byte[20];
                for(int j=0;j<20;j++)
                {
                    dataFor20[j]=buff[i*20+j];
                    ++length;
                }
                System.out.println("here1");
                System.out.println("here1:"+new String(dataFor20));
                Log.d("AppRunArrayLenght","超出20");
                //target_chara.setValue(dataFor20);
                mBluetoothLeService.writeCharacteristic(dataFor20);
                /*try {
                    Thread.sleep(12);//丢包处理
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
            }
            if(sendDatalens[1]!=0)
            {
                System.out.println("here2");
                byte[] lastData = new byte[buff.length%20];
                for(int i=0;i<sendDatalens[1];i++) {
                    lastData[i] = buff[sendDatalens[0] * 20 + i];
                    ++length;
                }
                String str=null;
                try {
                    str = new String(lastData, 0, sendDatalens[1],"GB2312");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                if (target_chara == null){
                    new Handler().post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(activity, "没建立连接，请检查设备...", Toast.LENGTH_SHORT).show();
                        }
                    });
                    return;
                }
                Log.d("AppRunArrayLenght","总发送长: "+length);
                for (byte lastDatum : lastData) {
                    Log.d("AppRunArrayLenght","lastDatum= "+lastDatum);
                }
                //target_chara.setValue(lastData);//   --->此行出空指针错误):
                mBluetoothLeService.writeCharacteristic(lastData);
                mBluetoothLeService.startSend(target_chara);
            }

        }


    }

    /* 意图过滤器 */
    private static IntentFilter makeGattUpdateIntentFilter()
    {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter
                .addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        return intentFilter;
    }

    private BluetoothLeService mBluetoothLeService;
    private final ServiceConnection mServiceConnection = new ServiceConnection()
    {

        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onServiceConnected(ComponentName componentName,
                                       IBinder service)
        {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service)
                    .getService();
            if (!mBluetoothLeService.initialize())
            {
                Log.e("TAG", "Unable to initialize Bluetooth");
                Toast.makeText(activity,"蓝牙初始化失败",Toast.LENGTH_SHORT).show();
//                finish();
                return;
            }
            Log.e("getPINNNNN","service started");
            // Automatically connects to the device upon successful start-up
            // initialization.
            // 根据蓝牙地址，连接设备
            mBluetoothLeService.connect(deviceBean.getDeviceMac());

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName)
        {
            mBluetoothLeService = null;
        }

    };

    public interface OnStatusListener{
        void onChange(String name,boolean connected);
    }

    public boolean getState(){
        return connect;
    }

    /**
     * 将数据分包
     *
     * **/
    public int[] dataSeparate(int len)
    {
        int[] lens = new int[2];
        lens[0]=len/20;
        lens[1]=len%20;
        return lens;
    }


    /**
     * @Title: displayGattServices
     * @Description: TODO(处理蓝牙服务)
     * @return void
     * @throws
     */
    private void displayGattServices(List<BluetoothGattService> gattServices)
    {

        if (gattServices == null)
            return;
        String uuid = null;
        String unknownServiceString = "unknown_service";
        String unknownCharaString = "unknown_characteristic";

        // 服务数据,可扩展下拉列表的第一级数据
        ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();

        // 特征数据（隶属于某一级服务下面的特征值集合）
        ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();

        // 部分层次，所有特征值集合
        mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

        // Loops through available GATT Services.
        for (BluetoothGattService gattService : gattServices)
        {

            // 获取服务列表
            HashMap<String, String> currentServiceData = new HashMap<String, String>();
            uuid = gattService.getUuid().toString();

            // 查表，根据该uuid获取对应的服务名称。SampleGattAttributes这个表需要自定义。

            gattServiceData.add(currentServiceData);

            System.out.println("Service uuid:" + uuid);

            ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();

            // 从当前循环所指向的服务中读取特征值列表
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService
                    .getCharacteristics();

            ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();

            // Loops through available Characteristics.
            // 对于当前循环所指向的服务中的每一个特征值
            for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics)
            {
                charas.add(gattCharacteristic);
                HashMap<String, String> currentCharaData = new HashMap<String, String>();
                uuid = gattCharacteristic.getUuid().toString();

                if (gattCharacteristic.getUuid().toString()
                        .equals(HEART_RATE_MEASUREMENT))
                {

                    // 测试读取当前Characteristic数据，会触发mOnDataAvailable.onCharacteristicRead()
                    new Handler().postDelayed(new Runnable()
                    {

                        @Override
                        public void run()
                        {
                            System.out.println("readCharacteristic");

                            mBluetoothLeService.setCharacteristicNotification(gattCharacteristic, true);

                            // TODO Auto-generated method stub
                            mBluetoothLeService
                                    .readCharacteristic(gattCharacteristic);
                        }
                    }, 200);

                    System.out.println("Client uuid:" + uuid);

                    // 接受Characteristic被写的通知,收到蓝牙模块的数据后会触发mOnDataAvailable.onCharacteristicWrite()
                    // mBluetoothLeService.setCharacteristicNotification(
                    //         gattCharacteristic, true);
                    target_chara = gattCharacteristic;

                    // 设置数据内容
                    // 往蓝牙模块写入数据
                    // mBluetoothLeService.writeCharacteristic(gattCharacteristic);
                }
                List<BluetoothGattDescriptor> descriptors = gattCharacteristic
                        .getDescriptors();
                for (BluetoothGattDescriptor descriptor : descriptors)
                {
                    System.out.println("---descriptor UUID:"
                            + descriptor.getUuid());
                    // 获取特征值的描述
                    mBluetoothLeService.getCharacteristicDescriptor(descriptor);
                    // mBluetoothLeService.setCharacteristicNotification(gattCharacteristic,
                    // true);
                }

                gattCharacteristicGroupData.add(currentCharaData);
            }
            // 按先后顺序，分层次放入特征值集合中，只有特征值
            mGattCharacteristics.add(charas);
            // 构件第二级扩展列表（服务下面的特征值）
            gattCharacteristicData.add(gattCharacteristicGroupData);

        }

    }

    public void onStopSend(){
        if (executorService != null && !executorService.isShutdown()) {
            executorService.shutdown();
        }
        if (mBluetoothLeService!=null){
            mBluetoothLeService.disconnect();
            mBluetoothLeService=null;
        }
        activity.unregisterReceiver(mGattUpdateReceiver);
    }
}
